/*--------------------------------------------------------------------------------------+
|
|     $Source: samples/SampleDgnDbEditor/Shipping%Class%ItemHandler.cpp $
|
|  $Copyright: (c) 2014 Bentley Systems, Incorporated. All rights reserved. $
|
+--------------------------------------------------------------------------------------*/
#include "SampleDgnDbEditor.h"

static Shipping%Class%ItemHandler* s_shipping%Class%ItemHandlerP;

//---------------------------------------------------------------------------------------
// @bsimethod
//---------------------------------------------------------------------------------------
PhysicalItemHandlerR Shipping%Class%ItemHandler::Get() 
    {
    if (!s_shipping%Class%ItemHandlerP)
        s_shipping%Class%ItemHandlerP = new Shipping%Class%ItemHandler();

    return *s_shipping%Class%ItemHandlerP;
    }

//---------------------------------------------------------------------------------------
// @bsimethod
//---------------------------------------------------------------------------------------
StatusInt Shipping%Class%ItemHandler::CreatePhysicalGeometry (PhysicalGeometryR localGeometry, double length, double diameter)
    {
    DPoint3d centerA = DPoint3d::FromZero();
    DPoint3d centerB = DPoint3d::From (length, 0.0, 0.0);
    double radius = diameter / 2.0;

    ISolidPrimitivePtr solidPtr = ISolidPrimitive::CreateDgnCone (DgnConeDetail (centerA, centerB, radius, radius, true));
    if (!solidPtr.IsValid())
        return BSIERROR;

    localGeometry.push_back (IGeometryPtr::Create (solidPtr));
    return BSISUCCESS;
    }

//---------------------------------------------------------------------------------------
// @bsimethod
//---------------------------------------------------------------------------------------
StatusInt Shipping%Class%ItemHandler::_GetPhysicalGeometry (PhysicalGeometryR localGeometry, TransformR localToWorld, ECDbR db, ECInstanceKeyCR instanceKey)
    {
    ECSqlStatement statement;
    ECSqlStatus prepareStatus = statement.Prepare (db, 
        "SELECT Placement.Origin,Placement.Yaw,Placement.Pitch,Placement.Roll,[Length],Diameter "
        "FROM SampleDgnDbEditor.Shipping%Class% WHERE ECInstanceId=?");

    if (ECSqlStatus::Success != prepareStatus)
        return BSIERROR;

    statement.BindId (1, instanceKey.GetECInstanceId());

    ECSqlStepStatus stepStatus = statement.Step();
    if (ECSqlStepStatus::HasRow != stepStatus)
        return BSIERROR;

    DPoint3d placementOrigin = statement.GetValuePoint3D (0);
    YawPitchRollAngles placementAngles = YawPitchRollAngles::FromDegrees (statement.GetValueDouble (1), statement.GetValueDouble (2), statement.GetValueDouble (3));

    localToWorld = placementAngles.ToTransform (placementOrigin);

    double length   = statement.GetValueDouble (4);
    double diameter = statement.GetValueDouble (5);

    return CreatePhysicalGeometry (localGeometry, length, diameter);
    }

//---------------------------------------------------------------------------------------
// @bsimethod
//---------------------------------------------------------------------------------------
StatusInt Shipping%Class%ItemHandler::_GetPhysicalGeometry (PhysicalGeometryR localGeometry, IECInstanceCR instance)
    {
    ECValue value;
    if (ECOBJECTS_STATUS_Success != instance.GetValue (value, L"Length"))
        return BSIERROR;

    double length = value.GetDouble();

    if (ECOBJECTS_STATUS_Success != instance.GetValue (value, L"Diameter"))
        return BSIERROR;

    double diameter = value.GetDouble();

    return CreatePhysicalGeometry (localGeometry, length, diameter);
    }

//---------------------------------------------------------------------------------------
// @bsimethod
//---------------------------------------------------------------------------------------
StatusInt Shipping%Class%ItemHandler::_GetInputProperties (PropertyVectorR propertyVector, ECClassCR ecClass)
    {
    // WIP: Should get property list from custom attribute instead!

    propertyVector.insert (propertyVector.begin(), ecClass.GetPropertyP (L"Length"));
    if (!propertyVector.front())
        return BSIERROR;

    propertyVector.insert (propertyVector.begin(), ecClass.GetPropertyP (L"Diameter"));
    if (!propertyVector.front())
        return BSIERROR;

    return BSISUCCESS;
    }

//---------------------------------------------------------------------------------------
// @bsimethod
//---------------------------------------------------------------------------------------
bool Shipping%Class%ItemHandler::_CanHandleClass (ECDbCR db, ECClassId ecClassId)
    {
    ECClassP ecClassP = NULL;
    if (BSISUCCESS != db.GetEC().GetSchemaManager().GetECClass (ecClassP, "SampleDgnDbEditor", "Shipping%Class%"))
        return false;

    return (ecClassP->GetId() == ecClassId);
    }

//---------------------------------------------------------------------------------------
// @bsimethod
//---------------------------------------------------------------------------------------
ECRelationshipClassCP Shipping%Class%ItemHandler::_GetRelationshipToTag (ECClassCR ecClass)
    {
    // WIP: Implement!
    return NULL;
    }
